import axios, { AxiosInstance, AxiosRequestConfig, AxiosPromise, AxiosResponse } from 'axios'
import qs from 'qs'
import { observable } from 'mobx'

interface AxiosConfig {
  withCredentials?: boolean
  baseURL?: string
  timeout: number
}

export interface HttpResult<R> {
  code: string
  message: string
  result: R
}

const axiosConfig: AxiosConfig = {
  timeout: 6000,
}

const POST_FORM_OPTION = {
  transformRequest: [
    function (data: any) {
      return qs.stringify(data)
    },
  ],
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
}

class Request {
  instance: AxiosInstance
  constructor(config: AxiosConfig) {
    this.instance = axios.create(config)
    this.interceptors(this.instance)
  }

  private interceptors(instance: AxiosInstance) {
    instance.interceptors.request.use(
      (config: AxiosRequestConfig) => {
        /**
         *    可以做的事
         * 1. 开启全屏loading动画
         * 2. 数据加密config.data
         * 3. 请求头加上token
         **/
        if (sessionStorage.getItem('token')) {
          config.headers.authorization = sessionStorage.getItem('token')
        }
        return config
      },
      (error) => {
        /** 请求错误
         * 1. 关闭全屏loading动画
         * 2. 提示错误信息
         **/
        console.log('axios request error', error)
        return Promise.reject(error)
      }
    )
    instance.interceptors.response.use(
      (response: AxiosResponse) => {
        /**
         * 1. 关闭全屏loading动画
         * 2. 数据解密
         * 3. 根据 response.data.code 做不同的错误处理
         **/

        const data = response.data
        const { code } = data

        if (code === '1') {
          Promise.resolve(response)
          return response
        }

        if (code !== '000000') {
        }
        return response
      },
      (error) => {
        /** 请求错误
         * 1. 关闭全屏loading动画
         * 2. 提示错误信息
         **/
        console.log('axios response error', error)
        return Promise.reject(error)
      }
    )
  }

  public get<T>(url: string, params?: object): AxiosPromise<HttpResult<T>> {
    return this.instance.get(url, { params })
  }

  public post<T>(url: string, params?: object, isFormData?: boolean): AxiosPromise<HttpResult<T>> {
    let options = isFormData ? POST_FORM_OPTION : {}
    return this.instance.post(url, params, options)
  }
}

export default new Request(axiosConfig)
